function reflect1(params: any) {
    return params
}
const string1 = reflect1('abc') // any
console.log('str1: ', string1, typeof(string1))
const number1 = reflect1(100) // any
console.log('str1: ', number1, typeof(number1))

console.log('========================')

function reflect2(params: unknown) {
    return params
}
const string2 = reflect2('abc') // unknown
console.log('str2: ', string2, typeof(string2))
const number2 = reflect2(100) // unknown
console.log('str2: ', number2, typeof(number2))

console.log('========================')

function reflect3<T>(params: T) {
    return params
}
const string3 = reflect3('abc') //'abc'
const number3 = reflect3(100) //100
const string4 = reflect3<string>('abc') //string
const number4 = reflect3<number>(100) //number

console.log('========================')

function reflect4<T>(params: T[]) {
    return params
}
const array1 = reflect4([1, 'a', 2])//  (string | number)[]
const array2 = reflect4<number>([1,2,3]) // number[]

console.log('========================')

function reflect5<T>(params: T): T {
    return params
}
const string5 = reflect5('abc') // "abc"
const number5 = reflect5(100) // 100
const string6 = reflect5<string>('abc') // string
const number6 = reflect5<number>(100) // number

console.log('========================')

class Memory<S> {
    store: S;
    constructor(store: S) {
        this.store = store;
    }
    set(store: S) {
        this.store = store;
    }
    get(): S {
        return this.store
    }
}
const numberMemory = new Memory<number>(1);
// numberMemory.set('a') 类型“string”的参数不能赋给类型“number”的参数。ts(2345)
console.log('number memory is : ', numberMemory.get());
numberMemory.set(100);
console.log('number memory is : ', numberMemory.get());

const stringMemory = new Memory<string>('abc');
console.log('string memory is : ', stringMemory.get());
// stringMemory.set(100); 类型“number”的参数不能赋给类型“string”的参数。ts(2345)
stringMemory.set('Hello memory');
console.log('string memory is : ', stringMemory.get());

type StringOrNumberArray<E> = E extends string | number ? E[] : E;
type StringArray = StringOrNumberArray<string>; // 类型是 string[]
type NumberArray = StringOrNumberArray<number>; // 类型是 number[]
type NeverGot = StringOrNumberArray<boolean>; // 类型是 boolean

type BooleanOrString = string | boolean;
type WhatIsThis = StringOrNumberArray<BooleanOrString>; // 好像应该是 string | boolean ?  --> boolean | string[]
type BooleanOrStringGot = BooleanOrString extends string | number ? BooleanOrString[] : BooleanOrString; //  string | boolean

interface ReduxModel<State> {
    state: State,
    reducers: {
        [action: string]: (state: State, action: any) => State
    }  
}

type ModelInterface = { id: number; name: string };

const model: ReduxModel<ModelInterface> = {
    state: { id: 1, name: '乾元' }, //  ok 类型必须是 ModelInterface
    reducers: {
        setId: (state, action: { payload: number }) => ({
            ...state,
            id: action.payload // ok must be number
        }),
        setName: (state, action: { payload: string }) => ({
            ...state,
            name: action.payload // ok must be string
        })
    }
}
